package gnacos

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/nacos-group/nacos-sdk-go/vo"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
)

func (registerService *RegisterService) HttpGet(scheme, applicationName, reqUrl string, params, headers map[string]string, resp interface{}) error {
	reqUrl, err := registerService.generateUrl(scheme, applicationName, reqUrl)
	if err != nil {
		return err
	}

	if params != nil {
		paramData := url.Values{}
		for key, val := range params {
			paramData.Set(key, val)
		}
		uri, err := url.ParseRequestURI(reqUrl)
		if err != nil {
			return err
		}
		uri.RawQuery = paramData.Encode()
		reqUrl = uri.String()
	}

	request, err := http.NewRequest(http.MethodGet, reqUrl, nil)
	if err != nil {
		return err
	}

	if headers != nil {
		for key, value := range headers {
			request.Header.Set(key, value)
		}
	}

	client := &http.Client{}
	get, err := client.Do(request)
	defer get.Body.Close()

	if err != nil {
		return err
	}

	return formatResult(get.Body, resp)
}

func (registerService *RegisterService) HttpPost(scheme, applicationName, reqUrl string, headers map[string]string, param, resp interface{}) error {
	//拼接url
	reqUrl, err := registerService.generateUrl(scheme, applicationName, reqUrl)
	if err != nil {
		return err
	}

	paramVal, _ := json.Marshal(param)
	request, err := http.NewRequest(http.MethodPost, reqUrl, bytes.NewBuffer(paramVal))
	if err != nil {
		return err
	}

	if headers != nil {
		for key, value := range headers {
			request.Header.Set(key, value)
		}
	}

	client := &http.Client{}
	get, err := client.Do(request)
	defer get.Body.Close()
	if err != nil {
		return err
	}

	return formatResult(get.Body, resp)
}

func (registerService *RegisterService) generateUrl(scheme, applicationName, url string) (string, error) {
	instance, err := registerService.iClient.SelectOneHealthyInstance(vo.SelectOneHealthInstanceParam{
		ServiceName: applicationName,
	})
	if err != nil {
		return "", err
	}
	reqUrl := scheme + "://" + instance.Ip + ":" + fmt.Sprintf("%d", instance.Port) + url

	return reqUrl, nil
}

func formatResult(resultReader io.Reader, resp interface{}) error {
	all, err := ioutil.ReadAll(resultReader)
	if err != nil {
		return err
	}
	json.Unmarshal(all, resp)
	return nil
}
